package com.dgut.lotterySystem.controller;

import com.dgut.lotterySystem.common.errorcode.ControllerErrorCodeConstants;
import com.dgut.lotterySystem.common.errorcode.ServiceErrorCodeConstants;
import com.dgut.lotterySystem.common.pojo.CommonResult;
import com.dgut.lotterySystem.common.pojo.exception.ControllerException;
import com.dgut.lotterySystem.common.pojo.exception.ServiceException;
import com.dgut.lotterySystem.common.utils.JacksonUtil;
import com.dgut.lotterySystem.controller.param.CreateActivityParam;
import com.dgut.lotterySystem.controller.param.PageParam;
import com.dgut.lotterySystem.controller.result.CreateActivityResult;
import com.dgut.lotterySystem.controller.result.FindActivityInfoListResult;
import com.dgut.lotterySystem.controller.result.GetActivityDetailResult;
import com.dgut.lotterySystem.service.dto.ActivityDetailDTO;
import com.dgut.lotterySystem.service.dto.ActivityInfoDTO;
import com.dgut.lotterySystem.service.dto.CreateActivityDTO;
import com.dgut.lotterySystem.service.dto.PageInfoListDTO;
import com.dgut.lotterySystem.service.impl.ActivityServiceImpl;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.query.Param;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Comparator;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/activity")
public class ActivityController {

    @Autowired
    private ActivityServiceImpl activityService;
    @Autowired
    private static final Logger logger= LoggerFactory.getLogger(ActivityController.class);

    /**
     *
     * @param param
     * @return
     */
    @RequestMapping("/create")
    public CommonResult<CreateActivityResult> createActivity(@Validated @RequestBody CreateActivityParam param){
        logger.info("createActivity CreateActivityParam"+param);
        CreateActivityDTO activityDTO=activityService.createActivity(param);
        return CommonResult.success(
                converterCreateActivity(activityDTO));
    }

    /**
     * 获取活动列表
     * @param param
     * @return
     */
    @GetMapping("/findActivityInfoList")
    public CommonResult<FindActivityInfoListResult> findActivityInfoList(PageParam param){
        logger.info("findActivityInfoList param="+ JacksonUtil.writeValueAsString(param));
        return CommonResult.success(
                converterFindActivityInfoListResult(
                        activityService
                                .findActivityInfoList(param)));
    }

    /**
     * 根据id获取活动详情
     * @param activityId
     * @return
     */
    @GetMapping("/getActivityDetail")
    public CommonResult<GetActivityDetailResult> getActivityDetail(Long activityId){
        logger.info("getActivityDetail activityId="+activityId);
        ActivityDetailDTO detailDTO=activityService.getActivityDetail(activityId);
        return CommonResult.success(converterGetActivityDetailResult(detailDTO));
    }

    private GetActivityDetailResult converterGetActivityDetailResult(ActivityDetailDTO detailDTO) {
        if(detailDTO==null){
            throw new ControllerException(ControllerErrorCodeConstants.FIND_Activity_DETAIL_ERROR);
        }
        GetActivityDetailResult result=new GetActivityDetailResult();
        result.setActivityId(detailDTO.getActivityId());
        result.setActivityName(detailDTO.getActivityName());
        result.setDesc(detailDTO.getDesc());
        result.setValid(detailDTO.getStatus().getMessage());
        result.setPrizes(detailDTO.getPrizeDTOList()
                        .stream()
                        .sorted(Comparator.comparingInt(
                                        prizeDTO->prizeDTO.getPrizeTier().getCode()))
                        .map(prizeDTO -> {
                            GetActivityDetailResult.Prize prize=new GetActivityDetailResult.Prize();
                            prize.setId(prizeDTO.getId());
                            prize.setName(prizeDTO.getName());
                            prize.setDescription(prizeDTO.getDescription());
                            prize.setPrice(prizeDTO.getPrice());
                            prize.setImageUrl(prizeDTO.getImageUrl());
                            prize.setPrizeTierName(prizeDTO.getPrizeTier().getMessage());
                            prize.setPrizeAmount(prizeDTO.getPrizeAmount());
                            prize.setValid(prizeDTO.valid());
                            return prize;
                        }).collect(Collectors.toList())
                );

        result.setUsers(detailDTO.getUserDTOList().stream().map(userDTO -> {
            GetActivityDetailResult.User user=new GetActivityDetailResult.User();
            user.setUserId(userDTO.getUserId());
            user.setUserName(userDTO.getUserName());
            user.setValid(userDTO.valid());
            return user;
        }).collect(Collectors.toList()));
        return result;
    }

    private FindActivityInfoListResult converterFindActivityInfoListResult(PageInfoListDTO<ActivityInfoDTO> activityInfoList) {
        if(activityInfoList==null){
            throw new ControllerException(ControllerErrorCodeConstants.FIND_Activity_INFO_LIST_ERROR);
        }
        FindActivityInfoListResult result=new FindActivityInfoListResult();
        result.setTotal(activityInfoList.getTotal());
        result.setRecords(activityInfoList.getRecords()
                .stream()
                .map(activityInfoDTO -> {
            FindActivityInfoListResult.ActivityInfo activityInfo=new FindActivityInfoListResult.ActivityInfo();
            activityInfo.setActivityId(activityInfoDTO.getActivityId());
            activityInfo.setActivityName(activityInfoDTO.getActivityName());
            activityInfo.setDescription(activityInfoDTO.getDescription());
            activityInfo.setValid(activityInfoDTO.valid());
            return activityInfo;
        }).collect(Collectors.toList()));
        return result;
    }


    private CreateActivityResult converterCreateActivity(CreateActivityDTO activityDTO) {
        if(activityDTO==null){
            throw new ControllerException(ControllerErrorCodeConstants.Activity_CREATE_ERROR);
        }
        CreateActivityResult activityResult= new CreateActivityResult();
        activityResult.setActivityId(activityDTO.getActivityId());
        return activityResult;
    }
}
